package com.spider.spiderflowable.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spider.spiderflowable.business.entity.dto.UserDTO;
import com.spider.spiderflowable.business.entity.dto.UserPasswordDTO;
import com.spider.spiderflowable.business.entity.model.User;
import com.spider.spiderflowable.business.entity.param.UserQueryParam;
import com.spider.spiderflowable.business.enums.DataDictionaryEnum;
import com.spider.spiderflowable.business.mapper.UserMapper;
import com.spider.spiderflowable.business.service.UserService;
import com.spider.spiderflowable.exception.BusinessException;
import com.spider.spiderflowable.exception.ExceptionDef;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * @author xiong.bo
 * @version 1.0
 * @date 2020/11/18 17:09
 */
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;


    @Override
    public Page<User> selectPage(UserQueryParam userQueryParam) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(userQueryParam.getMobile()), User::getMobile, userQueryParam.getMobile());
        queryWrapper.like(StringUtils.hasText(userQueryParam.getUsername()), User::getUsername, userQueryParam.getUsername());
        queryWrapper.eq(userQueryParam.getDataStatus() != null, User::getDataStatus, userQueryParam.getDataStatus());
        queryWrapper.orderByDesc(User::getCreateTime);
        return this.baseMapper.selectPage(userQueryParam.buildPage(), queryWrapper);
    }

    @Override
    public User findByUsername(String username) {
        if (!StringUtils.hasText(username)) {
            throw new BusinessException(ExceptionDef.ERROR_COMMON_PARAM_NULL);
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public User saveUser(UserDTO user) {
        if (!StringUtils.hasText(user.getUsername()) || !StringUtils.hasText(user.getPassword())) {
            throw new BusinessException(ExceptionDef.ERROR_COMMON_PARAM_NULL);
        }
        //用户名是唯一标识
        User exitsUser = findByUsername(user.getUsername());
        if (exitsUser != null) {
            throw new BusinessException(ExceptionDef.ERROR_USER_EXIST);
        }
        User userData = new User();
        userData.setUsername(user.getUsername());
        userData.setNickname(user.getNickname());
        userData.setMobile(user.getMobile());
        userData.setSex(user.getSex());
        userData.setPassword(passwordEncoder.encode(user.getPassword()));
        int s = DataDictionaryEnum.ENABLE.getCode().equals(user.getDataStatus()) ? DataDictionaryEnum.ENABLE.getCode()
                : DataDictionaryEnum.DISABLE.getCode();
        userData.setDataStatus(s);
        this.baseMapper.insert(userData);

        return userData;
    }

    /**
     * 修改用户，支持修改用户的以下信息
     * 电话号码，性别，启用状态
     *
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public User updateUser(UserDTO user) {
        User existUser = findById(user.getId());
        existUser.setNickname(user.getNickname());
        existUser.setMobile(user.getMobile());
        existUser.setSex(user.getSex());
        existUser.setEmail(user.getEmail());
        int s = DataDictionaryEnum.ENABLE.getCode().equals(user.getDataStatus()) ? DataDictionaryEnum.ENABLE.getCode()
                : DataDictionaryEnum.DISABLE.getCode();
        existUser.setDataStatus(s);
        this.baseMapper.updateById(existUser);

        return existUser;
    }

    @Override
    public User updatePassword(UserPasswordDTO userPasswordDto) {
        User existUser = findById(userPasswordDto.getId());
        if (StringUtils.isEmpty(userPasswordDto.getOldPassword()) || !userPasswordDto.getNewPassword().equals(userPasswordDto.getRenewPassword())) {
            throw new BusinessException(ExceptionDef.ERROR_PASSWORD_INCONSISTENCY);
        }
        //matches 方法解密来验证
        if (!passwordEncoder.matches(userPasswordDto.getOldPassword(), existUser.getPassword())) {
            throw new BusinessException(ExceptionDef.ERROR_PASSWORD_FAILED);
        }
        existUser.setPassword(passwordEncoder.encode(userPasswordDto.getNewPassword()));
        this.baseMapper.updateById(existUser);
        return existUser;
    }

    @Override
    public Boolean deleteUser(String ids) {
        if (ids == null) {
            return true;
        }
        List<Long> idList = new ArrayList<>();
        if (ids.contains(",")) {
            String[] splitArray = ids.split(",");
            for (String str : splitArray) {
                idList.add(Long.parseLong(str));
            }
        } else {
            idList.add(Long.parseLong(ids));
        }
        this.baseMapper.deleteBatchIds(idList);
        return true;
    }

    @Override
    public User findById(Long id) {
        User user = this.baseMapper.selectById(id);
        if (user == null) {
            throw new BusinessException(ExceptionDef.ERROR_DATA_NOT_EXIST);
        }
        return user;
    }

    @Cacheable(value = "BasicsCache:10m", key = "#id") // 缓存方法结果
    @Override
    public UserDTO findUserDtoById(Long id) {
        UserDTO userDTO = new UserDTO();
        User user = findById(id);
        BeanUtils.copyProperties(user, userDTO);
        return userDTO;
    }


    @Override
    public User enableUser(Long id, Integer status) {
        User user = findById(id);
        status = DataDictionaryEnum.ENABLE.getCode().equals(status) ? 1 : 0;
        user.setDataStatus(status);
        this.baseMapper.updateById(user);
        return user;
    }

    @Override
    public User resetAccountPassword(UserPasswordDTO userPasswordDto) {
        User existUser = findById(userPasswordDto.getId());
        if (!userPasswordDto.getNewPassword().equals(userPasswordDto.getRenewPassword())) {
            throw new BusinessException(ExceptionDef.ERROR_PASSWORD_INCONSISTENCY);
        }
        //获取当前登录用户是否是管理员
//        User adminUser = findById(userContentId);
//        List<SystemRole> roleList = adminUser.getRoleList();
//        List<String> ruleCodeList = new ArrayList<>();
//        if (roleList != null) {
//            ruleCodeList = roleList.stream().map(SystemRole::getRoleCode).collect(Collectors.toList());
//        }
//        if (!ruleCodeList.contains(DataDictionaryEnum.SYSTEM_ADMIN.getName())
//                && !ruleCodeList.contains(DataDictionaryEnum.ADMIN.getName())) {
//            throw new BusinessException(ExceptionDef.ERROR_USER_NOT_ADMIN);
//        }
        existUser.setPassword(passwordEncoder.encode(userPasswordDto.getNewPassword()));
        this.baseMapper.updateById(existUser);
        return existUser;
    }

    @Override
    public User getUserContent() {
        User user = null;
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (!Objects.isNull(principal)) {
            user = this.findByUsername(principal.toString());
        }
        if (Objects.isNull(user)) {
            throw new BusinessException(ExceptionDef.ERROR_USER_TOKEN_INVALID);
        }
        return user;
    }
}
